<template>
  <div class="upload-component">
    <el-upload
      ref="uploadRef"
      class="upload-demo"
      action="/api/upload"
      :auto-upload="true"
      :show-file-list="false"
      :on-success="handleSuccess"
      :on-error="handleError"
      :before-upload="beforeUpload"
      :multiple="multiple"
      style="display: none"
    >
    </el-upload>

    <div v-if="showImage" class="image-container">
      <el-image v-if="modelValue" :src="modelValue" fit="cover" :preview-src-list="[modelValue]">
        <template #error>
          <div class="image-slot">
            <el-icon><Picture /></el-icon>
          </div>
        </template>
      </el-image>
      <div v-else class="upload-placeholder">
        <el-icon><Upload /></el-icon>
        <span>等待上传</span>
      </div>
    </div>

    <div class="upload-actions">
      <el-button type="primary" class="upload-button" plain @click="triggerFileSelect">
        <el-icon class="icon"><Upload /></el-icon>
        <span>{{ modelValue ? '重新上传' : '选择图片' }}</span>
      </el-button>
      <el-button v-if="showCamera" type="primary" plain class="camera-button" @click="openCamera">
        <el-icon class="icon"><Camera /></el-icon>
        <span>拍照上传</span>
      </el-button>
    </div>
  </div>
</template>

<script setup>
import { ref, defineEmits, defineProps } from 'vue'
import { ElMessage } from 'element-plus'
import { Picture, Upload, Camera } from '@element-plus/icons-vue'

const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  multiple: {
    type: Boolean,
    default: false
  },
  showCamera: {
    type: Boolean,
    default: true
  },
  maxSize: {
    type: Number,
    default: 5
  },
  showImage: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['update:modelValue', 'upload-success', 'upload-error'])

const uploadRef = ref(null)

const triggerFileSelect = () => {
  uploadRef.value.$el.querySelector('input[type="file"]').click()
}

const openCamera = () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = 'image/*'
  input.capture = 'environment'
  input.onchange = e => {
    const file = e.target.files[0]
    if (file) {
      const formData = new FormData()
      formData.append('file', file)
      uploadRef.value.submit(formData)
    }
  }
  input.click()
}

const handleSuccess = (response, file) => {
  emit('update:modelValue', response.url)
  emit('upload-success', { response, file })
  ElMessage.success('上传成功')
}

const handleError = (error, file) => {
  emit('upload-error', { error, file })
  ElMessage.error('上传失败，请重试')
}

const beforeUpload = file => {
  const isImage = file.type.startsWith('image/')
  const isLt5M = file.size / 1024 / 1024 < props.maxSize

  if (!isImage) {
    ElMessage.error('只能上传图片文件！')
    return false
  }
  if (!isLt5M) {
    ElMessage.error(`图片大小不能超过 ${props.maxSize}MB！`)
    return false
  }
  return true
}
</script>

<style lang="scss" scoped>
.upload-component {
  .image-container {
    height: 180px;
    background-color: #f5f7fa;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    overflow: hidden;
    margin-bottom: 12px;

    @media screen and (max-width: 768px) {
      height: 160px;
    }

    .el-image {
      width: 100%;
      height: 100%;
    }

    .image-slot,
    .upload-placeholder {
      display: flex;
      flex-direction: column;
      align-items: center;
      color: #909399;

      .el-icon {
        font-size: 30px;
        margin-bottom: 8px;
      }
    }
  }

  .upload-actions {
    display: flex;
    gap: 12px;
    justify-content: center;

    .upload-button,
    .camera-button {
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 8px 16px;

      .icon {
        margin-right: 8px;
        font-size: 16px;
      }
    }
  }
}
</style>
